surface: Be smarter about autohide
authorMatthias Clasen <mclasen@redhat.com>
Tue, 3 Nov 2020 20:28:40 +0000 (15:28 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Wed, 4 Nov 2020 19:56:30 +0000 (14:56 -0500)
When we close grabbing popups due to an outside
click, check at each level if the click is still
outside. This makes closing the nested popover
menu in the popover on page 3 of widget-factory
work as expected, when you click the menubutton
again.

gdk/gdksurface.c

index 00990ea40e273dc1467aaf097e4cf88ea659aea2..6d8e92aec3bd56d27ac26e6975877dad458372a9 100644 (file)
@@ -2657,18 +2657,6 @@ gdk_synthesize_surface_state (GdkSurface       *surface,
   gdk_surface_set_state (surface, (surface->state | set_flags) & ~unset_flags);
 }
 
-static void
-hide_popup_chain (GdkSurface *surface)
-{
-  GdkSurface *parent;
-
-  gdk_surface_hide (surface);
-
-  parent = surface->parent;
-  if (parent->autohide)
-    hide_popup_chain (parent);
-}
-
 static gboolean
 check_autohide (GdkEvent *event)
 {
@@ -2695,13 +2683,23 @@ check_autohide (GdkEvent *event)
       device = gdk_event_get_device (event);
       if (gdk_device_grab_info (display, device, &grab_surface, NULL))
         {
-          GdkSurface *event_surface = gdk_event_get_surface (event);
+          GdkSurface *event_surface;
+
+          event_surface = gdk_event_get_surface (event);
 
           if (grab_surface != event_surface &&
               grab_surface != event_surface->parent &&
               grab_surface->autohide)
             {
-              hide_popup_chain (grab_surface);
+              GdkSurface *surface = grab_surface;
+
+              do
+                {
+                  gdk_surface_hide (surface);
+                  surface = surface->parent;
+                }
+              while (surface->autohide && surface != event_surface);
+
               return TRUE;
             }
         }